#include <signal.h>
#include <unistd.h>

#include <iostream>
using std::cout;
using std::endl;
using std::string;

#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/RedisMessage.h>

using std::vector;

//通过构造函数初始化计数器的值 
static WFFacilities::WaitGroup waitGroup(1);

void sighandler(int num)
{
    printf("sig %d is coming\n", num);
    //将计数器的值减1
    waitGroup.done();
}

void seriesCallback(const SeriesWork * series)
{
    printf("seriesCallback is running.\n");
    int * pnumber = (int*)series->get_context();
    if(pnumber) {
        delete pnumber;
        pnumber = nullptr;
    }
}

void redisCallback(WFRedisTask * redistask)
{
    printf("redisCallback is running.\n");

    //0. 对任务的状态进行检测
    int state = redistask->get_state();
    int error = redistask->get_error();
    switch(state) {
    case WFT_STATE_SYS_ERROR:
        printf("sys error: %s\n", strerror(error)); break;
    case WFT_STATE_DNS_ERROR:
        printf("dns error: %s\n", gai_strerror(error)); break;
    case WFT_STATE_SUCCESS:
        break;
    }
    if(state != WFT_STATE_SUCCESS) {
        printf("task error!\n");
        return;
    }
    
    //1. 打印请求信息
    auto req = redistask->get_req();
    string command;
    vector<string> params;
    req->get_command(command);
    req->get_params(params);
    cout << "request: " << command << " ";
    for(auto & param : params) {
        cout << param << " ";
    }
    cout << endl << endl;
    
    //2. 打印响应信息
    using namespace protocol;
    auto resp = redistask->get_resp();
    RedisValue result;
    resp->get_result(result);

    if(command == "HSET") {
        //在第一个任务中设置序列的上下文信息
        int * pnumber = new int(10);
        printf("*pnumber: %d, %p\n", *pnumber, pnumber);
        series_of(redistask)->set_context(pnumber);
        series_of(redistask)->set_callback(seriesCallback);
    } else if(command == "HGETALL") {
        //在第二个任务中获取序列的上下文信息
        int * p1 = (int*)series_of(redistask)->get_context();
        printf("*p1: %d, %p\n", *p1, p1);
    }

    if(result.is_string()) {
        cout << "response is string\n";
        cout << result.string_value() << endl;
    } else if(result.is_int()) {
        cout << "response is int\n";
        cout << result.int_value() << endl;
        //4. 创建Redis任务
        string url("redis://127.0.0.1:6379");
        auto redisTask2 = WFTaskFactory::create_redis_task(url, 1, redisCallback);
        //用第一个任务的user_data赋值给第二个任务的user_data
        redisTask2->user_data = redistask->user_data;
        //5. 设置任务的属性
        string command2("HGETALL");
        std::vector<string> params2{"liubei"};
        redisTask2->get_req()->set_request(command2, params2);
        //通过序列添加新的子任务
        series_of(redistask)->push_back(redisTask2);

    } else if(result.is_array()) {
        cout << "response is array\n";
        for(size_t i = 0; i < result.arr_size(); ++i) { 
            cout << (i + 1) << ") " 
                 << result.arr_at(i).string_value()  << endl;
        }
    }
}


void test0()
{
    signal(SIGINT, sighandler);


    //1. 创建Redis任务
    string url("redis://127.0.0.1:6379");
    auto redisTask1 = WFTaskFactory::create_redis_task(url, 1, redisCallback);

    //2. 设置任务的属性
    string command("HSET");
    std::vector<string> params{"liubei", "age", "40", "sex", "male"};
    redisTask1->get_req()->set_request(command, params);
    //3. 交给框架来调度执行
    redisTask1->start();

    //在主线程中直接设置序列的context，是有风险的;
    //因此不能直接在这里设置
    //series_of(redisTask1)->set_context(&number);
    waitGroup.wait();

}


int main()
{
    test0();
    printf("exit main\n");
    return 0;
}

